package daybook.model.transaction;

import daybook.util.Utils;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collector;

public class TransactionSummaryStatistics implements Consumer<Transaction> {
    private LocalDate minDate = LocalDate.MAX;
    private LocalDate maxDate = LocalDate.MIN;
    private long transactionCount;

    public LocalDate getMinDate() {
        return minDate;
    }

    public LocalDate getMaxDate() {
        return maxDate;
    }

    public long getTransactionCount() {
        return transactionCount;
    }

    public double getTransactionCountPerDay() {
        final long days = minDate.until(maxDate.plusDays(1), ChronoUnit.DAYS);
        return days > 0 ? (double) transactionCount / days : 0.0d;
    }

    @Override
    public void accept(Transaction transaction) {
        transactionCount++;
        minDate = Utils.min(transaction.getDate(), minDate);
        maxDate = Utils.max(transaction.getDate(), maxDate);
    }

    public void combine(TransactionSummaryStatistics other) {
        transactionCount += other.transactionCount;
        minDate = Utils.min(minDate, other.minDate);
        maxDate = Utils.max(maxDate, other.maxDate);
    }

    public static TransactionSummaryStatistics ofOrderedTransactions(List<Transaction> transactions) {
        final TransactionSummaryStatistics statistics = new TransactionSummaryStatistics();
        if (!transactions.isEmpty()) {
            statistics.minDate = transactions.get(0).getDate();
            statistics.maxDate = transactions.get(transactions.size() - 1).getDate();
        }
        statistics.transactionCount = transactions.size();
        return statistics;
    }

    private static Collector<Transaction, TransactionSummaryStatistics, TransactionSummaryStatistics> TRANSACTIONS_SUMMARY_STATISTICS_COLLECTOR = Collector.of(
            TransactionSummaryStatistics::new,
            TransactionSummaryStatistics::accept,
            (tss1, tss2) -> {tss1.combine(tss2); return tss1;}
    );
    public static Collector<Transaction, TransactionSummaryStatistics, TransactionSummaryStatistics> collector() {
        return TRANSACTIONS_SUMMARY_STATISTICS_COLLECTOR;
    }

    @Override
    public String toString() {
        return "TransactionSummaryStatistics{" +
                "minDate=" + minDate +
                ", maxDate=" + maxDate +
                ", transactionCount=" + transactionCount +
                ", transactionCountPerDay=" + getTransactionCountPerDay() +
                '}';
    }
}
